using System;
using System.Globalization;
using System.Web.Mvc;
using RecruitmentAgency.Models.DataTypes;

namespace RecruitmentAgency.Models.Validation
{
    ///<summary>
    /// The RecruitmentAgency.Models.Utilities.AccountValidator provides all the methods necessary
    ///</summary>
    public class AccountValidator : BaseValidator
    {
        private ModelStateDictionary modelState;
        private int minimumPasswordLength;

        /// <summary>
        /// Initialises a new RecruitmentAgency.Validation.CvValidator instance
        /// </summary>
        public AccountValidator(ModelStateDictionary modelState, string selectMessage, int minimumPasswordLength): base(selectMessage)
        {
            this.modelState = modelState;
            this.minimumPasswordLength = minimumPasswordLength;
        }

        /// <summary>
        /// Validate the user input for the change of password
        /// </summary>
        /// <param name="currentPassword">The current user password</param>
        /// <param name="newPassword">The new user password</param>
        /// <param name="confirmPassword">The confirmation password - must match the new password to pass the test</param>
        /// <returns>Returns true is the validation is passed</returns>
        public bool ValidateChangePassword(string currentPassword, string newPassword, string confirmPassword)
        {
            if (string.IsNullOrEmpty(currentPassword)) modelState.AddModelError("currentPassword", "You must specify a current password.");
            if (newPassword == null || newPassword.Length < minimumPasswordLength) modelState.AddModelError("newPassword", string.Format(CultureInfo.CurrentCulture, "You must specify a new password of {0} or more characters.", minimumPasswordLength));
            if (!string.Equals(newPassword, confirmPassword, StringComparison.Ordinal))modelState.AddModelError("_FORM", "The new password and confirmation password must match.");
            return modelState.IsValid;
        }

        /// <summary>
        /// Validate the user input for the user Login, it is responsible for the check of the user credenntial in the database
        /// </summary>
        /// <param name="login">The user's login details</param>
        /// <returns>Returns true if the user's credential have been verified</returns>
        public bool ValidateLogOn(Login login)
        {
            if (login.IsNull) return false;
            if (IsEmpty(login.UserName)) modelState.AddModelError("UserName", "This field is required.");
            if (IsEmpty(login.Password)) modelState.AddModelError("Password", "This field is required.");
            return modelState.IsValid;
        }

        /// <summary>
        /// Validate the use input for the job provider
        /// </summary>
        /// <param name="jobProvider">An instance of the RegisterJobProvider containing all the information necessary for a company registratio</param>
        /// <returns>Returns true if the Company's details are verified</returns>
        public bool ValidateRegistrationJobProvider(RegisterJobProvider jobProvider)
        {
            if (jobProvider.IsNull) return false;
            if (IsEmpty(jobProvider.CompanyName)) modelState.AddModelError("CompanyName", "This field is required.");
            if (IsEmpty(jobProvider.JobProviderUserName)) modelState.AddModelError("JobProviderUserName", "This field is required.");
            if (IsEmpty(jobProvider.JobProviderPassword)) modelState.AddModelError("JobProviderPassword", "This field is required.");
            if (IsEmpty(jobProvider.JobProviderConfirmPassword)) modelState.AddModelError("JobProviderConfirmPassword", "This field is required.");
            if (IsEmpty(jobProvider.FirstName)) modelState.AddModelError("FirstName", "This field is required.");
            if (IsEmpty(jobProvider.LastName)) modelState.AddModelError("LastName", "This field is required.");
            if (IsEmpty(jobProvider.AddressLine1)) modelState.AddModelError("AddressLine1", "This field is required.");
            if (IsEmpty(jobProvider.Town)) modelState.AddModelError("Town", "This field is required.");
            if (IsEmpty(jobProvider.PostCode)) modelState.AddModelError("PostCode", "This field is required.");
            if (IsEmpty(jobProvider.CompanyName)) modelState.AddModelError("CompanyName", "This field is required.");
            if (IsEmpty(jobProvider.RegistrationNumber)) modelState.AddModelError("RegistrationNumber", "This field is required.");
            if (IsEmpty(jobProvider.WebsiteUrl)) modelState.AddModelError("WebsiteUrl", "This field is required.");
            if (IsEmpty(jobProvider.Email)) modelState.AddModelError("Email", "This field is required.");
            if (ValidateEmail(jobProvider.Email)) modelState.AddModelError("Email", "Please enter a valid e-mail address.");
            if (ValidateUrl(jobProvider.WebsiteUrl)) modelState.AddModelError("WebsiteUrl", "Please enter a valid website URL.");
            if (ValidateSelection(jobProvider.Title)) modelState.AddModelError("Title", "This field is required.");
            if (jobProvider.JobProviderPassword.Length < minimumPasswordLength) modelState.AddModelError("JobProviderPassword", string.Format(CultureInfo.CurrentCulture, "You must specify a password of {0} or more characters.", minimumPasswordLength));
            if (!string.IsNullOrEmpty(jobProvider.JobProviderPassword) && (!string.IsNullOrEmpty(jobProvider.JobProviderConfirmPassword)) && !string.Equals(jobProvider.JobProviderPassword, jobProvider.JobProviderConfirmPassword, StringComparison.Ordinal)) modelState.AddModelError("JobProviderConfirmPassword", "The password and confirmation password must match.");
            return modelState.IsValid;
        }

        /// <summary>
        /// Validate the the job seeker details
        /// </summary>
        /// <param name="register">The instance of Register containing all the information regarding the Job seeker</param>
        /// <returns>Returns true if the details are correct</returns>
        public bool ValidateRegistration(Register register)
        {
            if (register.IsNull) return false;
            if (IsEmpty(register.RegisterFirstName)) modelState.AddModelError("RegisterFirstName", "This field is required.");
            if (IsEmpty(register.RegisterLastName)) modelState.AddModelError("RegisterLastName", "This field is required.");
            if (IsEmpty(register.RegisterUserName)) modelState.AddModelError("RegisterUserName", "This field is required.");
            if (IsEmpty(register.PersonalEmail)) modelState.AddModelError("PersonalEmail", "This field is required.");
            if (IsEmpty(register.RegisterPassword)) modelState.AddModelError("RegisterPassword", "This field is required.");
            if (IsEmpty(register.RegisterConfirmPassword)) modelState.AddModelError("RegisterConfirmPassword", "This field is required.");
            if (ValidateEmail(register.PersonalEmail)) modelState.AddModelError("PersonalEmail", "Please enter a valid e-mail address.");
            if (ValidateSelection(register.RegisterTitle)) modelState.AddModelError("RegisterTitle", "This field is required.");
            if (register.RegisterPassword.Length < minimumPasswordLength) modelState.AddModelError("RegisterPassword", string.Format(CultureInfo.CurrentCulture, "You must specify a password of {0} or more characters.", minimumPasswordLength));
            if (!string.Equals(register.RegisterPassword, register.RegisterConfirmPassword, StringComparison.Ordinal)) modelState.AddModelError("confirmPassword", "The password and confirmation password must match.");
            return modelState.IsValid;
        }
    }
}